package com.zmn.oms.api.controller.order;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.base.common.data.common.dro.area.AreaDRO;
import com.zmn.base.common.data.dubbo.interfaces.area.AreaListRemoteService;
import com.zmn.base.product.dubbo.interfaces.product.foreign.ProductForeignListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.constant.StatusConsts;
import com.zmn.common.utils.request.RequestUtil;
import com.zmn.oms.business.interfaces.work.masterwork.MasterWorkBService;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.order.open.AvailableTimeslotsQuery;
import com.zmn.oms.model.dto.order.proxy.*;
import com.zmn.oms.model.dto.work.masterwork.MasterVisitQrDTO;
import com.zmn.oms.model.entity.order.OrderListQuery;
import com.zmn.oms.model.entity.order.OrderQuery;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.order.CheckServicePointVO;
import com.zmn.oms.model.vo.order.open.AvailableTimeslotsVO;
import com.zmn.oms.model.vo.order.proxy.OrderInfoVO;
import com.zmn.oms.model.vo.work.OrderVisitQrCodeVO;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.proxy.ProxyOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Optional;

/**
 * 类描述：旧平台订单接口代理
 *
 * @author liuying
 * @date 2019/02/16 17:35
 */
@RestController
@RequestMapping("/proxy/order")
@Slf4j
public class ProxyOrderController {

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    AreaListRemoteService areaListRemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private ProductForeignListRemoteService productForeignListRemoteService;

    @Autowired
    private ProxyOrderBService proxyOrderBService;
    @Autowired
    private MasterWorkBService masterWorkBService;
    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private WorkFlowContextBService workFlowContextBService;
    /**
     * 订单查询
     *
     * @param orderQuery 订单信息
     * @return
     */
    @RequestMapping("/query")
    @ResponseBody
    public ResultDTO queryOrderById(@Valid OrderQuery orderQuery) {
        try {

            OrderInfoVO orderInfoVO = proxyOrderBService.queryOrderById(orderQuery);
            return ResultDTO.success(orderInfoVO);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }

    /**
     * 数量查询
     *
     * @param orderListQuery
     * @return
     */
    @RequestMapping("/query/count")
    public ResultDTO orderListCount(OrderListQuery orderListQuery) {
        if (orderListQuery.getChannelId() == null) {
            return ResultDTO.fail("渠道不能为空");
        }
        return ResultDTO.success(proxyOrderBService.orderListCount(orderListQuery));
    }

    /**
     * 通过列表
     *
     * @param orderListQuery
     * @return
     */
    @RequestMapping("/query/list")
    public ResultDTO orderList(OrderListQuery orderListQuery) {
        if (orderListQuery.getChannelId() == null) {
            return ResultDTO.fail("渠道不能为空");
        }
        List<OrderInfoVO> list = proxyOrderBService.orderList(orderListQuery);
        return ResultDTO.success(list);
    }

    /**
     * 通过用户ID列表
     *
     * @param orderListQuery
     * @return
     */
    @RequestMapping("/list")
    public ResultDTO orderListByUserId(OrderListQuery orderListQuery) {

        if (StringUtils.isBlank(orderListQuery.getOuterUserId()) && orderListQuery.getUserId() == null) {
            return ResultDTO.fail("用户信息不能为空");
        }
        List<OrderInfoVO> list = proxyOrderBService.orderList(orderListQuery);
        return ResultDTO.success(list);
    }

    /**
     * 创建订单
     *
     * @param createOrderDTO 订单信息
     * @return
     */
    @PostMapping("/create")
    @ResponseBody
    public ResultDTO createOrder(@Valid @RequestBody CreateOrderDTO createOrderDTO) {
        try {
            log.info("[Old-Proxy-API] CreateOrderDTO=[{}]", JSON.toJSONString(createOrderDTO));

            OrderBO orderBO = proxyOrderBService.createOrder(createOrderDTO);

            // 工单自动流转
            OrderWork orderWork = orderBO.getOrderWork();

            try {
                workFlowContextBService.asyncAutoFlow(orderWork.getOrderId(),orderWork.getWorkId());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }

            return ResultDTO.success(orderBO.getOrder());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }

    /**
     * 修改订单
     *
     * @param updateOrderDTO 订单信息
     * @return
     */
    @PostMapping("/update")
    @ResponseBody
    public ResultDTO updateOrder(@Valid @RequestBody UpdateOrderDTO updateOrderDTO) {
        try {
            log.info("[Old-Proxy-API] UpdateOrderDTO=[{}]", JSON.toJSONString(updateOrderDTO));

            proxyOrderBService.updateOrder(updateOrderDTO);
            return ResultDTO.success();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }

    /**
     * 取消订单
     *
     * @param cancelOrderDTO 订单信息
     * @return
     */
    @PostMapping("/cancel")
    @ResponseBody
    public ResultDTO cancelOrder(@Valid @RequestBody CancelOrderDTO cancelOrderDTO) {
        try {
            log.info("[Old-Proxy-API] CancelOrderDTO=[{}]", JSON.toJSONString(cancelOrderDTO));

            proxyOrderBService.cancelOrder(cancelOrderDTO);
            return ResultDTO.success();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }

    /**
     * 订单支付
     *
     * @param payOrderDTO 订单信息
     * @return
     */
    @PostMapping("/pay")
    @ResponseBody
    public ResultDTO payOrder(@Valid @RequestBody PayOrderDTO payOrderDTO) {
        try {
            log.info("[Old-Proxy-API] PayOrderDTO=[{}]", JSON.toJSONString(payOrderDTO));

            proxyOrderBService.payOrder(payOrderDTO);

            try {
                workFlowContextBService.asyncAutoFlow(payOrderDTO.getOrderId(),payOrderDTO.getWorkId());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }

            return ResultDTO.success();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }

    /**
     * 添加日志
     *
     * @param orderLogDTO 日志
     * @return
     */
    @PostMapping("/addLog")
    @ResponseBody
    public ResultDTO addOrderLog(@Valid @RequestBody OrderLogDTO orderLogDTO) {
        try {
            log.info("[Old-Proxy-API] OrderLogDTO=[{}]", JSON.toJSONString(orderLogDTO));

            proxyOrderBService.addOrderLog(orderLogDTO);
            return ResultDTO.success();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }

    /**
     * 评价
     *
     * @param commentDTO 评价
     * @return
     */
    @PostMapping("/addComment")
    @ResponseBody
    public ResultDTO addComment(@Valid @RequestBody CommentDTO commentDTO) {
        try {
            log.info("[Old-Proxy-API] CommentDTO=[{}]", JSON.toJSONString(commentDTO));

            proxyOrderBService.addComment(commentDTO);
            return ResultDTO.success();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }

    /**
     * 上门扫码
     *
     * @param orderId 订单Id
     * @param openId  微信openId
     * @return
     */
    @GetMapping("/visitQrCode")
    @ResponseBody
    public ResultDTO visitQrCode(@Valid @NotNull Long orderId, @NotNull String openId, @NotNull String auth) {

        if (!GlobalConsts.AUTH_INFO.equals(auth)) {
            return ResultDTO.fail("auth fail");
        }

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);

        try {
            MasterVisitQrDTO visitQrDTO = new MasterVisitQrDTO();
            visitQrDTO.setOrderId(orderId);
            visitQrDTO.setWorkId(orderId);
            visitQrDTO.setOpenId(openId);
            visitQrDTO.setDbOrderWork(orderWork);

            visitQrDTO.setOperatorId(orderWork.getUserId());
            visitQrDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_USER);
            visitQrDTO.setOperator(GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_USER));

            OrderVisitQrCodeVO qrCodeVO = masterWorkBService.visitUserQrCode(visitQrDTO);
            return ResultDTO.success(qrCodeVO);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }

//    /**
//     * 支付扫码
//     *
//     * @param orderId 订单Id
//     * @param openId  微信openId
//     * @return
//     */
//    @GetMapping("/payQrCode")
//    @ResponseBody
//    public ResultDTO payQrCode(@Valid @NotNull Long orderId, @NotNull String openId, @NotNull String auth) {
//
//        if (!GlobalConsts.AUTH_INFO.equals(auth)) {
//            return ResultDTO.fail("auth fail");
//        }
//
//        try {
//            orderWorkBService.payQrCode(orderId, openId);
//            return ResultDTO.success();
//        } catch (Exception e) {
//            e.printStackTrace();
//            return ResultDTO.fail("操作失败：" + e.getMessage());
//        }
//    }

    /**
     * 判断服务范围
     *
     * @param cityId      城市ID
     * @param servCategId 省份ID
     * @param longitude   经度
     * @param latitude    纬度
     * @return
     */
    @RequestMapping(value = "checkServicePoint")
    @ResponseBody
    public ResultDTO checkServicePoint(Integer cityId, Integer servCategId, Double longitude, Double latitude) {
        com.zmn.common.dto2.ResponseDTO<AreaDRO> areaResponseDTO = areaListRemoteService.getAreaByLatAndLng(longitude, latitude);
        AreaDRO areaDRO = areaResponseDTO.getData();
        if (areaDRO == null) {
            return ResultDTO.fail("区域信息不存在");
        }

        CheckServicePointVO detailVO = new CheckServicePointVO();
        detailVO.setCityId(areaDRO.getParentId());
        detailVO.setCountyId(areaDRO.getAreaId());
        detailVO.setCountyName(areaDRO.getName());
        detailVO.setStatus(GlobalConsts.YES);
        return ResultDTO.success(detailVO);
    }

    private boolean validIP(HttpServletRequest request) {
        String requestIp = RequestUtil.getRequestIp(request);
        List<String> ipList = Lists.newArrayList("10.51.61.37", "");
        for (String ip : ipList) {
            if (requestIp.contains(ip)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 查询预约时间
     *
     * @param query
     * @return
     */
    @PostMapping("/queryAvailableTimeslots")
    public ResultDTO queryAvailableTimes(@Valid @RequestBody AvailableTimeslotsQuery query) {
        try {
            log.info("[Old-Proxy-API] 查询预约时间：request=[{}]", JSON.toJSONString(query));

            List<AvailableTimeslotsVO> availableTimeslotsList = proxyOrderBService.queryAvailableTimeslots(query);

            log.info("[Old-Proxy-API] 查询预约时间：response：{}", JSON.toJSONString(availableTimeslotsList));

            return ResultDTO.success(availableTimeslotsList);
        } catch (OmsBaseException e) {
            log.error(String.format("[Old-Proxy-API] 查询预约时间失败：%s", e.getMessage()), e);
            return ResultDTO.fail(Optional.ofNullable(e.getCode()).orElse(StatusConsts.STATUS_ERROR), e.getMessage());
        } catch (Exception e) {
            log.error(String.format("[Old-Proxy-API] 查询预约时间失败：%s", e.getMessage()), e);
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }
}
